<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Adding a new algorithm to the Facemark API</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d3/d81/tutorial_contrib_root.html">Tutorials for contrib modules</a></li><li class="navelem"><a class="el" href="../../d5/d47/tutorial_table_of_content_facemark.html">Tutorial on Facial Landmark Detector API</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Adding a new algorithm to the Facemark API </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>Goals </h2>
<p>In this tutorial you will learn how to:</p><ul>
<li>integrate a new algorithm of facial landmark detector into the Facemark API</li>
<li>compile a specific contrib module</li>
<li>using extra parameters in a function</li>
</ul>
<h2>Explanation </h2>
<ul>
<li><p class="startli"><b>Add the class header</b></p>
<p class="startli">The class header for a new algorithm should be added to a new file in include/opencv2/face. Here is the template that you can use to integrate a new algorithm, change the FacemarkNEW to a representative name of the new algorithm and save it using a representative filename accordingly.</p>
</li>
</ul>
<div class="fragment"><div class="line"><span class="keyword">class </span><a class="code" href="../../db/de0/group__core__utils.html#ga67ea671a3582ce612ac3c281e067f480">CV_EXPORTS_W</a> FacemarkNEW : <span class="keyword">public</span> Facemark {</div><div class="line"><span class="keyword">public</span>:</div><div class="line">    <span class="keyword">struct </span>CV_EXPORTS Config {</div><div class="line">        Config();</div><div class="line"></div><div class="line">        <span class="comment">/*read only parameters - just for example*/</span></div><div class="line">        <span class="keywordtype">double</span> detect_thresh;         </div><div class="line">        <span class="keywordtype">double</span> sigma;                 </div><div class="line"></div><div class="line">        <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a9afba2f5b9bf298c62da8cf66184e41f">read</a>(<span class="keyword">const</span> FileNode&amp; <span class="comment">/*fn*/</span>);</div><div class="line">        <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a027b764f14e54f8838b5120e991bd29c">write</a>(FileStorage&amp; <span class="comment">/*fs*/</span>) <span class="keyword">const</span>;</div><div class="line">    };</div><div class="line"></div><div class="line">    <span class="comment">/*Builder and destructor*/</span></div><div class="line">    <span class="keyword">static</span> Ptr&lt;FacemarkNEW&gt; create(<span class="keyword">const</span> FacemarkNEW::Config &amp;conf = FacemarkNEW::Config() );</div><div class="line">    <span class="keyword">virtual</span> ~FacemarkNEW(){};</div><div class="line">};</div></div><!-- fragment --><ul>
<li><p class="startli"><b>Add the implementation code</b></p>
<p class="startli">Create a new file in the source folder with name representing the new algorithm. Here is the template that you can use.</p>
</li>
</ul>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d3/dc8/face_8hpp.html">opencv2/face.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;precomp.hpp&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a></div><div class="line">{</div><div class="line">    FacemarkNEW::Config::Config(){</div><div class="line">        detect_thresh = 0.5;</div><div class="line">        sigma=0.2;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a9afba2f5b9bf298c62da8cf66184e41f">FacemarkNEW::Config::read</a>( <span class="keyword">const</span> <a class="code" href="../../de/dd9/classcv_1_1FileNode.html">cv::FileNode</a>&amp; fn ){</div><div class="line">        *<span class="keyword">this</span> = FacemarkNEW::Config();</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (!fn[<span class="stringliteral">&quot;detect_thresh&quot;</span>].empty())</div><div class="line">            fn[<span class="stringliteral">&quot;detect_thresh&quot;</span>] &gt;&gt; detect_thresh;</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (!fn[<span class="stringliteral">&quot;sigma&quot;</span>].empty())</div><div class="line">            fn[<span class="stringliteral">&quot;sigma&quot;</span>] &gt;&gt; sigma;</div><div class="line"></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a027b764f14e54f8838b5120e991bd29c">FacemarkNEW::Config::write</a>( <a class="code" href="../../da/d56/classcv_1_1FileStorage.html">cv::FileStorage</a>&amp; fs )<span class="keyword"> const</span>{</div><div class="line">        fs &lt;&lt; <span class="stringliteral">&quot;detect_thresh&quot;</span> &lt;&lt; detect_thresh;</div><div class="line">        fs &lt;&lt; <span class="stringliteral">&quot;sigma&quot;</span> &lt;&lt; sigma;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/*implementation of the algorithm is in this class*/</span></div><div class="line">    <span class="keyword">class </span>FacemarkNEWImpl : <span class="keyword">public</span> FacemarkNEW {</div><div class="line">    <span class="keyword">public</span>:</div><div class="line">        FacemarkNEWImpl( <span class="keyword">const</span> FacemarkNEW::Config &amp;conf = FacemarkNEW::Config() );</div><div class="line"></div><div class="line">        <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a9afba2f5b9bf298c62da8cf66184e41f">read</a>( <span class="keyword">const</span> FileNode&amp; <span class="comment">/*fn*/</span> );</div><div class="line">        <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a027b764f14e54f8838b5120e991bd29c">write</a>( FileStorage&amp; <span class="comment">/*fs*/</span> ) <span class="keyword">const</span>;</div><div class="line"></div><div class="line">        <span class="keywordtype">void</span> loadModel(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename);</div><div class="line"></div><div class="line">        <span class="keywordtype">bool</span> setFaceDetector(<span class="keywordtype">bool</span>(*f)(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> , <a class="code" href="../../dc/d84/group__core__basic.html#gaad17fda1d0f0d1ee069aebb1df2913c0">OutputArray</a>, <span class="keywordtype">void</span> * extra_params));</div><div class="line">        <span class="keywordtype">bool</span> <a class="code" href="../../db/d7c/group__face.html#ga62cec28ecffa694e1efb272ff0c65da2">getFaces</a>( <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image , <a class="code" href="../../dc/d84/group__core__basic.html#gaad17fda1d0f0d1ee069aebb1df2913c0">OutputArray</a> faces, <span class="keywordtype">void</span> * extra_params);</div><div class="line"></div><div class="line">        Config config;</div><div class="line"></div><div class="line">    <span class="keyword">protected</span>:</div><div class="line"></div><div class="line">        <span class="keywordtype">bool</span> addTrainingSample(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image, <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> landmarks);</div><div class="line">        <span class="keywordtype">void</span> training();</div><div class="line">        <span class="keywordtype">bool</span> fit(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image, <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> faces, <a class="code" href="../../dc/d84/group__core__basic.html#gaf77c9a14ef956c50c1efd4547f444e63">InputOutputArray</a> landmarks, <span class="keywordtype">void</span> * runtime_params);</div><div class="line"></div><div class="line">        Config config; <span class="comment">// configurations</span></div><div class="line"></div><div class="line">        <span class="comment">/*proxy to the user defined face detector function*/</span></div><div class="line">        bool(*faceDetector)(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> , <a class="code" href="../../dc/d84/group__core__basic.html#gaad17fda1d0f0d1ee069aebb1df2913c0">OutputArray</a>, <span class="keywordtype">void</span> * );</div><div class="line">    }; <span class="comment">// class</span></div><div class="line"></div><div class="line">    Ptr&lt;FacemarkNEW&gt; FacemarkNEW::create(<span class="keyword">const</span> FacemarkNEW::Config &amp;conf){</div><div class="line">        <span class="keywordflow">return</span> Ptr&lt;FacemarkNEWImpl&gt;(<span class="keyword">new</span> FacemarkNEWImpl(conf));</div><div class="line">    }</div><div class="line"></div><div class="line">    FacemarkNEWImpl::FacemarkNEWImpl( <span class="keyword">const</span> FacemarkNEW::Config &amp;conf ) :</div><div class="line">        config( conf )</div><div class="line">    {</div><div class="line">        <span class="comment">// other initialization</span></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">bool</span> FacemarkNEWImpl::addTrainingSample(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image, <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> landmarks){</div><div class="line">        <span class="comment">// pre-process and save the new training sample</span></div><div class="line">        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> FacemarkNEWImpl::training(){</div><div class="line">        printf(<span class="stringliteral">&quot;training\n&quot;</span>);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">bool</span> FacemarkNEWImpl::fit(</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image,</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> faces,</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#gaf77c9a14ef956c50c1efd4547f444e63">InputOutputArray</a> landmarks,</div><div class="line">        <span class="keywordtype">void</span> * runtime_params)</div><div class="line">    {</div><div class="line">        <span class="keywordflow">if</span>(runtime_params!=0){</div><div class="line">            <span class="comment">// do something based on the extra parameters</span></div><div class="line">        }</div><div class="line"></div><div class="line">        printf(<span class="stringliteral">&quot;fitting\n&quot;</span>);</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a9afba2f5b9bf298c62da8cf66184e41f">FacemarkNEWImpl::read</a>( <span class="keyword">const</span> <a class="code" href="../../de/dd9/classcv_1_1FileNode.html">cv::FileNode</a>&amp; fn ){</div><div class="line">        config.read( fn );</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> <a class="code" href="../../d2/d75/namespacecv.html#a027b764f14e54f8838b5120e991bd29c">FacemarkNEWImpl::write</a>( <a class="code" href="../../da/d56/classcv_1_1FileStorage.html">cv::FileStorage</a>&amp; fs )<span class="keyword"> const </span>{</div><div class="line">        config.write( fs );</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> FacemarkNEWImpl::loadModel(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename){</div><div class="line">        <span class="comment">// load the model</span></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">bool</span> FacemarkNEWImpl::setFaceDetector(<span class="keywordtype">bool</span>(*f)(<a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> , <a class="code" href="../../dc/d84/group__core__basic.html#gaad17fda1d0f0d1ee069aebb1df2913c0">OutputArray</a>, <span class="keywordtype">void</span> * extra_params )){</div><div class="line">        faceDetector = f;</div><div class="line">        isSetDetector = <span class="keyword">true</span>;</div><div class="line">        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">bool</span> <a class="code" href="../../db/d7c/group__face.html#ga62cec28ecffa694e1efb272ff0c65da2">FacemarkNEWImpl::getFaces</a>( <a class="code" href="../../dc/d84/group__core__basic.html#ga353a9de602fe76c709e12074a6f362ba">InputArray</a> image , <a class="code" href="../../dc/d84/group__core__basic.html#gaad17fda1d0f0d1ee069aebb1df2913c0">OutputArray</a> roi, <span class="keywordtype">void</span> * extra_params){</div><div class="line">        <span class="keywordflow">if</span>(!isSetDetector){</div><div class="line">            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(extra_params!=0){</div><div class="line">            <span class="comment">//extract the extra parameters</span></div><div class="line">        }</div><div class="line"></div><div class="line">        std::vector&lt;Rect&gt; &amp; faces = *(std::vector&lt;Rect&gt;*)roi.getObj();</div><div class="line">        faces.clear();</div><div class="line"></div><div class="line">        faceDetector(image.getMat(), faces, extra_params);</div><div class="line"></div><div class="line">        <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment --><ul>
<li><p class="startli"><b>Compiling the code</b></p>
<p class="startli">Clear the build folder and then rebuild the entire library. Note that you can deactivate the compilation of other contrib modules by adding "-D BUILD_opencv_&lt;MODULE_NAME&gt;=OFF" flag to the cmake. After that you can execute make command in "&lt;build_folder&gt;/modules/face" to speed up the compiling process.</p>
</li>
</ul>
<h2>Best Practice </h2>
<ul>
<li><p class="startli"><b>Handling the extra parameters</b> To handle the extra parameters, a new struct should be created to holds all the required parameters. Here is an example of of a parameters container </p><div class="fragment"><div class="line">struct CV_EXPORTS Params</div><div class="line">{</div><div class="line">    Params( Mat rot = Mat::eye(2,2,CV_32F),</div><div class="line">            Point2f trans = Point2f(0.0,0.0),</div><div class="line">            float scaling = 1.0</div><div class="line">    );</div><div class="line"></div><div class="line">    Mat R;</div><div class="line">    Point2f t;</div><div class="line">    float scale;</div><div class="line">};</div></div><!-- fragment --><p class="startli">Here is a snippet to extract the extra parameters: </p><div class="fragment"><div class="line">if(runtime_params!=0){</div><div class="line">    Telo*  conf = (Telo*)params;</div><div class="line">    Params* params</div><div class="line">    std::vector&lt;Params&gt; params = *(std::vector&lt;Params&gt;*)runtime_params;</div><div class="line">    for(size_t i=0; i&lt;params.size();i++){</div><div class="line">        fit(img, landmarks[i], params[i].R,params[i].t, params[i].scale);</div><div class="line">    }</div><div class="line">}else{</div><div class="line">    // do something</div><div class="line">}</div></div><!-- fragment --><p class="startli">And here is an example to pass the extra parameter into fit function </p><div class="fragment"><div class="line">FacemarkAAM::Params * params = new FacemarkAAM::Params(R,T,scale);</div><div class="line">facemark-&gt;fit(image, faces, landmarks, params)</div></div><!-- fragment --><p class="startli">In order to understand this scheme, here is a simple example that you can try to compile and see how it works. </p><div class="fragment"><div class="line">struct Params{</div><div class="line">    int x,y;</div><div class="line">    Params(int _x, int _y);</div><div class="line">};</div><div class="line">Params::Params(int _x,int _y){</div><div class="line">    x = _x;</div><div class="line">    y = _y;</div><div class="line">}</div><div class="line"></div><div class="line">void test(int a, void * params=0){</div><div class="line">    printf(&quot;a:%i\n&quot;, a);</div><div class="line">    if(params!=0){</div><div class="line">        Params*  params = (Params*)params;</div><div class="line">        printf(&quot;extra parameters:%i %i\n&quot;, params-&gt;x, params-&gt;y);</div><div class="line">    }</div><div class="line">}</div><div class="line"></div><div class="line">int main(){</div><div class="line">    Params* params = new Params(7,22);</div><div class="line">    test(99, params);</div><div class="line">    return 0;</div><div class="line">}</div></div><!-- fragment --></li>
<li><b>Minimize the dependency</b> It is highly recomended to keep the code as small as possible when compiled. For this purpose, the developers are ecouraged to avoid the needs of heavy dependency such as <code>imgcodecs</code> and <code>highgui</code>.</li>
<li><b>Documentation and examples</b> Please update the documentation whenever needed and put example code for the new algorithm.</li>
<li><b>Test codes</b> An algorithm should be accompanied with its corresponding test code to ensure that the algorithm is compatible with various types of environment (Linux, Windows64, Windows32, Android, etc). There are several basic test that should be performed as demonstrated in the test/test_facemark_lbf.cpp file including cration of its instance, add training data, perform the training process, load a trained model, and perform the fitting to obtain facial landmarks.</li>
<li><b>Data organization</b> It is advised to divide the data for a new algorithm into 3 parts : <div class="fragment"><div class="line">class CV_EXPORTS_W FacemarkNEW : public Facemark {</div><div class="line">public:</div><div class="line">    struct CV_EXPORTS Params</div><div class="line">    {</div><div class="line">        // variables utilized as extra parameters</div><div class="line">    }</div><div class="line">    struct CV_EXPORTS Config</div><div class="line">    {</div><div class="line">        // variables used to configure the algorithm</div><div class="line">    }</div><div class="line">    struct CV_EXPORTS Model</div><div class="line">    {</div><div class="line">        // variables to store the information of model</div><div class="line">    }</div><div class="line"></div><div class="line">    static Ptr&lt;FacemarkNEW&gt; create(const FacemarkNEW::Config &amp;conf = FacemarkNEW::Config() );</div><div class="line">    virtual ~FacemarkNEW(){};</div><div class="line">}</div></div><!-- fragment --> </li>
</ul>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:38 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
